#include <iostream>
#include <vector>
using namespace std;

class Trie {
	struct trie_node {
		int pass = 0, end = 0;
		vector<trie_node *> next{ vector<trie_node *>(26, nullptr) };
	};
	trie_node *root = new trie_node;

	void remove(trie_node *root)
	{
		if (root) {
			for (auto p : root->next) {
				if (p) {
					remove(p);
				}
			}
			delete root;
		}
	}

    public:
	void insert(const string &s)
	{
		trie_node *node = root;
		node->pass++;
		int i = 0, id = 0;
		while (i < s.length()) {
			id = s[i++] - 'a';
			if (node->next[id] == nullptr) {
				node->next[id] = new trie_node;
			}
			node = node->next[id];
			node->pass++;
		}
		node->end++;
	}

	void erase(const string &s)
	{
		if (search(s) > 0) {
			trie_node *node = root;
			node->pass--;
			int i = 0, id = 0;
			while (i < s.length()) {
				id = s[i++] - 'a';
				if (--node->next[id]->pass == 0) {
					remove(node->next[id]);
					node->next[id] = nullptr;
					return;
				}
				node = node->next[id];
			}
			node->end--;
		}
	}

	int search(const string &s)
	{
		trie_node *node = root;
		int i = 0, id = 0;
		while (i < s.length()) {
			id = s[i++] - 'a';
			if (node->next[id] == nullptr) {
				return 0;
			}
			node = node->next[id];
		}
		return node->end;
	}

	int prefix(const string &s)
	{
		trie_node *node = root;
		int i = 0, id = 0;
		while (i < s.length()) {
			id = s[i++] - 'a';
			if (node->next[id] == nullptr) {
				return 0;
			}
			node = node->next[id];
		}
		return node->pass;
	}
};

class Trie2 {
	enum { MAXN = 150001 };
	int tree[MAXN][26] = {};
	int end[MAXN] = {};
	int pass[MAXN] = {};
	int cnt = 1;

    public:
	void insert(const string &s)
	{
		int cur = 1;
		pass[cur]++;
		for (int i = 0, id; i < s.length(); i++) {
			id = s[i] - 'a';
			if (tree[cur][id] == 0) {
				tree[cur][id] = ++cnt;
			}
			cur = tree[cur][id];
			pass[cur]++;
		}
		end[cur]++;
	}

	int search(const string &s)
	{
		int cur = 1;
		for (int i = 0, id; i < s.length(); i++) {
			id = s[i] - 'a';
			if (tree[cur][id] == 0) {
				return 0;
			}
			cur = tree[cur][id];
		}
		return end[cur];
	}

	int prefix(const string &s)
	{
		int cur = 1;
		for (int i = 0, id; i < s.length(); i++) {
			id = s[i] - 'a';
			if (tree[cur][id] == 0) {
				return 0;
			}
			cur = tree[cur][id];
		}
		return pass[cur];
	}

	void erase(const string &s)
	{
		if (search(s) > 0) {
			int cur = 1;
			pass[cur]--;
			for (int i = 0, id; i < s.length(); i++) {
				id = s[i] - 'a';
				if (--pass[tree[cur][id]] == 0) {
					tree[cur][id] = 0;
                                        return;
				}
                                cur = tree[cur][id];
			}
                        end[cur]--;
		}
	}
};
Trie2 trie;
int main()
{
	int n, op;
	string s;
	cin >> n;
	//Trie2 trie;
	while (n--) {
		cin >> op >> s;
		switch (op) {
		case 1:
			trie.insert(s);
			break;
		case 2:
			trie.erase(s);
			break;
		case 3:
			cout << (trie.search(s) == 0 ? "NO" : "YES") << endl;
			break;
		case 4:
			cout << trie.prefix(s) << endl;
		}
	}
	return 0;
}